

  

  

<main class="main-container ng-scope" ng-view="">
<div class="main receptacle post-view ng-scope">

  <article class="entry ng-scope" ng-controller="EntryCtrl" ui-lightbox="">
    <header>
      <h1 class="entry-title ng-binding">Wordpress 评论功能Xss 始末</h1>

      <div class="entry-meta">
        <a target="_blank" class="author name ng-binding">
          Stefanie</a>
        <span class="bull">·</span>
        <time title="2015/05/11 10:03" ui-time="" datetime="2015/05/11 10:03" class="published ng-binding ng-isolate-scope">2015/05/11 10:03</time>
      </div>
    </header>

    <!-- ngIf: isCensoring -->

    <section class="entry-content ng-binding" ng-bind-html="postContentTrustedHtml">
      <p>
        </p><p>近期Wordpress自身程序评论功能的Xss在微博上沸沸扬扬，而其中的修复过程也可谓一波三折，接下来由我为大家一一讲述。</p>

<h1>WordPress &lt;4.1.2 xss</h1>

<hr>

<p>该问题来自于特殊字符截断，mysql官网描述“The character set named utf8 uses a maximum of three bytes per character and contains only BMP characters”，mysql在使用utf8编码时，单个字符大小上限为3字节，当出现超过3个字节的utf8字符时，则会出现由于数据库不识别字符而产生截断效果。示例如下，使用特殊字符：</p>

<p><!--more--></p>

<p><img alt="enter image description here" img-src="da4c18f13bd7d9fee45bcb1596b58af5aea19894.jpg"></p>

<pre><code>#!sql
UPDATE `wp_comments` SET `comment_content` = 'stefanie[特殊字符]555555 ' WHERE `wp_comments`.`comment_ID` =12;
</code></pre>

<p>在数据库中插入的结果为stefanie，特殊字符及后面的内容并未插入数据库。</p>

<p>UTF-8编码在对于不同的字符区域，编码所占用的字节数各不相同。</p>

<p><img alt="enter image description here" img-src="dd79f40c1890c94a81ecf9dcfd03705e4be611e1.jpg"></p>

<p>mysql utf-8编码对于占用四个字节的字符无法识别，使用上图范围内的编码均可达到目的，如</p>

<p><img alt="enter image description here" img-src="9f378c953344de905f5b9e02ae05d4621bf9aff5.jpg"> <img alt="enter image description here" img-src="7738d0a420303c34ac3b1b5e9eebb2bd054bfa0f.jpg"> <img alt="enter image description here" img-src="d0a6e20814c3fc77e6c0da98077a5ff9db7f976d.jpg"></p>

<p>当mysql的编码为utf-8mb4或者latin1时，则可以对此类字符进行识别，另外，当mysql开启strict mode时候，会更加严格地处理，确保在数据有效存储之前进行阻止，也就不会产生该问题。</p>

<p>关于漏洞利用，Wordpress只允许评论中出现白名单内的标签和对应的属性，而且要保证标签的完整性，比如尖括号的闭合。Poc如下：</p>

<pre><code>#!html
&lt;abbr title="123 onmouseover=alert(1) 特殊字符"&gt;
</code></pre>

<p>可以看出，onmouseover是在双引号内作为title属性的值出现的，在插入数据库时由于特殊字符产生截断，右侧的引号不会插入，在输出时，左侧引号会被转义，因而可使得onmouseover成功解析。 相关链接：</p>

<p>(1] http://xteam.baidu.com/?p=177 (2]https://cedricvb.be/post/wordpress-stored-xss-vulnerability-4-1-2/ (3]https://dev.mysql.com/doc/refman/5.5/en/charset-unicode-utf8mb4.html</p>

<h1>WordPress &lt;=4.2 xss</h1>

<hr>

<p>mysql type＝TEXT时，TEXT的最大长度为64kb，当发生数据库的插入操作时，则会将大于64KB的部分抛弃，此时也造成了一种截断，而wordpress保存评论的字段的type正是TEXT。</p>

<p>该漏洞于上一漏洞同理，只是截断的方式有所不同，poc如下：</p>

<pre><code>#!html
&lt;abbr title="123 onmouseover=alert(1) 此处增加无用字符至64KB "&gt;
</code></pre>

<p>截断效果如下图：</p><p></p>

<p><img alt="enter image description here" img-src="8c11f7c902fd4ac8ec012a96917da30570019632.jpg"></p>

<p><img alt="enter image description here" img-src="7e5da77781b652c842cb2d1b17ec6f73c5b649ce.jpg"></p>

<p>该poc仅限IE使用，而Klikki Oy团队给出了兼容多种浏览器的POC，chrome，IE，firefox测试成功。</p>

<pre><code>#!html
stefanie&lt;a title='x onmouseover=alert(unescape(/hello%20world/.source))
style=position:absolute;left:0;top:0;width:5000px;height:5000px  此处用特殊字符或者长度截断均可'&gt;&lt;/a&gt;
</code></pre>

<p>相关链接： (1] http://xteam.baidu.com/?p=177 (2] https://speakerdeck.com/mathiasbynens/hacking-with-unicode</p>

<h1>WordPress &lt;=4.2.1 xss</h1>

<hr>

<p>4.2.1版本主要针对长度截断进行了修复，在wp-includes\wp-db.php get&#95;col&#95;length函数中增加了数据库每种类型字段的长度限制，并和传入数据长度做了比较。</p>

<pre><code>#!php
protected function process_field_lengths( $data, $table ) {
foreach ( $data as $field =&gt; $value ) {
    if ( '%d' === $value['format'] || '%f' === $value['format'] ) {
            // We can skip this field if we know it isn't a string.
            // This checks %d/%f versus ! %s because it's sprintf() could take more.
            $value['length'] = false;
        } else {
            $value['length'] = $this-&gt;get_col_length( $table, $field );
            if ( is_wp_error( $value['length'] ) ) {
                return false;
            }
        }
        if ( false !== $value['length'] &amp;&amp; mb_strlen( $value['value'] ) &gt; $value['length'] ) {
            return false;
        }
        $data[ $field ] = $value;
    }
    return $data;
}
</code></pre>

<p>$value['length']来自于get&#95;col&#95;length，text类型长度上限为65535字节，mb&#95;strlen( $value['value'] )是mb&#95;strlen函数来统计字符个数的结果，两个值的计量单位不同，一个是字节数，一个是字符的个数。</p>

<p><img alt="enter image description here" img-src="a57782554a2d8205c58b09487aebc117a50aa1c2.jpg"></p>

<p>在函数“mb_strlen”中，一个多字节字符统计个数为1。在不同的编码中，一个字符的大小可以为多个字节（多字节字符），所以我们可以构造一个字符串，让字符的个数小于65535而字符串的字节数大于65535字节，从而满足如下条件：</p>

<pre><code>#!sql
if ( false !== $value['length'] &amp;&amp; mb_strlen( $value['value'] ) &gt; $value['length'] ) {
                return false;}
</code></pre>

<p>当php向数据库中插入数据时，由于字节数超过了text类型的长度上线65535字节，所以字符串会被截断，导致了之前的xss可以重新被利用。 相关链接：</p>

<p>(1] http://xteam.baidu.com/?p=198 (2] http://php.net/manual/zh/function.mb-strlen.php</p>

<h1>WordPress 4.2.2 中总体修复情况</h1>

<hr>

<p>在4.2.2版本中引入了两个变量：</p>

<p>$truncate&#95;by&#95;byte&#95;length ： 是否进行字节长度验证 $needs&#95;validation ： 是否进行多字节字符合规性验证以及长度验证 wp422/wp-includes/wp-db.php 2626行</p>

<pre><code>#!sql
if ( $truncate_by_byte_length ) {
    mbstring_binary_safe_encoding();
    if ( false !== $length &amp;&amp; strlen( $value['value'] ) &gt; $length ) {
        $value['value'] = substr( $value['value'], 0, $length );
    }
    reset_mbstring_encoding();
    if ( ! $needs_validation ) {
        continue;
    }
}
</code></pre>

<p>该处解决了4.2.1中用mb_strlen来测量实际长度和规定长度上线之间的比较造成的问题，改用了strlen来测量长度，并对超长部分进行切割，因而拦截了4.2.1补丁bypass造成的xss。</p>

<pre><code>#!sql
$regex = '/
    (
        (?: [\x00-\x7F]                  # single-byte sequences   0xxxxxxx
        |   [\xC2-\xDF][\x80-\xBF]       # double-byte sequences   110xxxxx 10xxxxxx
        |   \xE0[\xA0-\xBF][\x80-\xBF]   # triple-byte sequences   1110xxxx 10xxxxxx * 2
        |   [\xE1-\xEC][\x80-\xBF]{2}
        |   \xED[\x80-\x9F][\x80-\xBF]
        |   [\xEE-\xEF][\x80-\xBF]{2}';
if ( 'utf8mb4' === $charset ) {
    $regex .= '
        |    \xF0[\x90-\xBF][\x80-\xBF]{2} # four-byte sequences   11110xxx 10xxxxxx * 3
        |    [\xF1-\xF3][\x80-\xBF]{3}
        |    \xF4[\x80-\x8F][\x80-\xBF]{2}
    ';
}
$regex .= '){1,40}                          # ...one or more times
    )
    | .                                  # anything else
    /x';
$value['value'] = preg_replace( $regex, '$1', $value['value'] );
if ( false !== $length &amp;&amp; mb_strlen( $value['value'], 'UTF-8' ) &gt; $length ) {
    $value['value'] = mb_substr( $value['value'], 0, $length, 'UTF-8' );
}
continue;
}
</code></pre>

<p>可以看出，对于utf8编码时，仅仅会取范围内的小于等于3字节UTF8字符，取出之后，会按照当前多字节字符的编码长度再次确认。此处是针对小于4.2版本用四字节utf8字符插入数据库截断以及其他特殊字符截断而修补的。 相关链接：</p>

<p>(1] https://wordpress.org/news/2015/05/wordpress-4-2-2/</p>

<p>致谢：感谢evil_xi4oyu的每一次悉心指点和yaseng的帮助~</p>      <p></p>
    </section>
  </article>
  <!-- collect -->
  <div class="entry-controls clearfix">
		<div style="float:left;color:#9d9e9f;font-size:15px">
			<span>
				&copy;乌云知识库版权所有 未经许可 禁止转载
			</span>
		</div>
        

      </div>

          
  <!-- collect end -->
  <!-- recommend -->
  <div class="yarpp-related">
<h3>为您推荐了适合您的技术文章:</h3>
<ol id="recommandsystem">
		<li><a href="http://drops.wooyun.org/papers/9510" rel="bookmark" id="re1">WordPress 利用 XMLRPC 高效爆破 原理分析</a></li>
			<li><a href="http://drops.wooyun.org/papers/596" rel="bookmark" id="re2">WordPress < 3.6.1 PHP 对象注入漏洞</a></li>
			<li><a href="http://drops.wooyun.org/papers/10511" rel="bookmark" id="re3">利用基于 NTP 的 TOTP 算法缺陷绕过 WordPress 登陆验证</a></li>
			<li><a href="http://drops.wooyun.org/papers/8988" rel="bookmark" id="re4">WordPress Vulnerability Analysis (CVE-2015-5714 &amp; CVE-2015-5715)</a></li>
	 
</ol>
</div>
  <!-- recommend end -->
  <!-- comment -->
  <div id="comments" class="comment-list clearfix">
            
          <div id="comment-list">
    
    <div class="note-comment">
      <img class="avatar" alt="30" src="http://wooyun.b0.upaiyun.com/wooyun_job/avatar/default.png">
      <div class="content">
        <div class="comment-header">
          <span class="author-link">6666666666666</span>
                 <span class="reply-time">2015-11-05 20:54:35</span>
        </div>
        <p></p><p>这些截断的符号 要怎么打进去？</p>
<p></p>
        
      </div>
    </div>
    
    <div class="note-comment">
      <img class="avatar" alt="30" src="http://wooyun.b0.upaiyun.com/wooyun_job/avatar/default.png">
      <div class="content">
        <div class="comment-header">
          <span class="author-link"><a class="__cf_email__" href="/cdn-cgi/l/email-protection" data-cfemail="1e767f7d757b6c5e6d77707f307d70">[email&#160;protected]</a></span>
                 <span class="reply-time">2015-06-03 14:56:13</span>
        </div>
        <p></p><p>时总我爱你。</p>
<p></p>
        
      </div>
    </div>
    
    <div class="note-comment">
      <img class="avatar" alt="30" src="http://wooyun.b0.upaiyun.com/wooyun_job/avatar/default.png">
      <div class="content">
        <div class="comment-header">
          <span class="author-link">炼金术师</span>
                 <span class="reply-time">2015-05-14 09:59:00</span>
        </div>
        <p></p><p>时总，牛！</p>
<p></p>
        
      </div>
    </div>
    
    <div class="note-comment">
      <img class="avatar" alt="30" src="http://wooyun.b0.upaiyun.com/wooyun_job/avatar/default.png">
      <div class="content">
        <div class="comment-header">
          <span class="author-link">Yaseng</span>
                 <span class="reply-time">2015-05-13 13:47:02</span>
        </div>
        <p></p><p>前排支持  </p>
<p></p>
        
      </div>
    </div>
    
    <div class="note-comment">
      <img class="avatar" alt="30" src="http://wooyun.b0.upaiyun.com/wooyun_job/avatar/default.png">
      <div class="content">
        <div class="comment-header">
          <span class="author-link">齐迹</span>
                 <span class="reply-time">2015-05-13 10:46:20</span>
        </div>
        <p></p><p>@stone  可以用html &#65799;(后面数字大于65535)就可以了</p>
<p></p>
        
      </div>
    </div>
    
    <div class="note-comment">
      <img class="avatar" alt="30" src="http://wooyun.b0.upaiyun.com/wooyun_job/avatar/default.png">
      <div class="content">
        <div class="comment-header">
          <span class="author-link">齐迹</span>
                 <span class="reply-time">2015-05-13 09:27:56</span>
        </div>
        <p></p><p>大部分网站开启strict mode 估计网站就各种报错了！<br>
尤其是php</p>
<p></p>
        
      </div>
    </div>
    
    <div class="note-comment">
      <img class="avatar" alt="30" src="http://wooyun.b0.upaiyun.com/wooyun_job/avatar/default.png">
      <div class="content">
        <div class="comment-header">
          <span class="author-link">liyang</span>
                 <span class="reply-time">2015-05-12 16:40:58</span>
        </div>
        <p></p><p>这个截断也有可能影响别的应用吧~</p>
<p></p>
        
      </div>
    </div>
    
    <div class="note-comment">
      <img class="avatar" alt="30" src="http://wooyun.b0.upaiyun.com/wooyun_job/avatar/default.png">
      <div class="content">
        <div class="comment-header">
          <span class="author-link">mramydnei</span>
                 <span class="reply-time">2015-05-11 23:46:02</span>
        </div>
        <p></p><p>修的不地道</p>
<p></p>
        
      </div>
    </div>
    
    <div class="note-comment">
      <img class="avatar" alt="30" src="http://wooyun.b0.upaiyun.com/wooyun_job/avatar/default.png">
      <div class="content">
        <div class="comment-header">
          <span class="author-link">存在敏感词</span>
                 <span class="reply-time">2015-05-11 19:53:06</span>
        </div>
        <p></p><p>为什么我感觉wp的这些修复是治标不治本呢。。</p>
<p></p>
        
      </div>
    </div>
    
    <div class="note-comment">
      <img class="avatar" alt="30" src="http://wooyun.b0.upaiyun.com/wooyun_job/avatar/default.png">
      <div class="content">
        <div class="comment-header">
          <span class="author-link">Comer</span>
                 <span class="reply-time">2015-05-11 16:50:14</span>
        </div>
        <p></p><p>时总 nb...虽然不知道时总是谁 - -#</p>
<p></p>
        
      </div>
    </div>
    
    <div class="note-comment">
      <img class="avatar" alt="30" src="http://wooyun.b0.upaiyun.com/wooyun_job/avatar/default.png">
      <div class="content">
        <div class="comment-header">
          <span class="author-link">livers</span>
                 <span class="reply-time">2015-05-11 13:29:20</span>
        </div>
        <p></p><p>顶 时总</p>
<p></p>
        
      </div>
    </div>
    
    <div class="note-comment">
      <img class="avatar" alt="30" src="http://wooyun.b0.upaiyun.com/wooyun_job/avatar/default.png">
      <div class="content">
        <div class="comment-header">
          <span class="author-link">lupin</span>
                 <span class="reply-time">2015-05-11 10:29:38</span>
        </div>
        <p></p><p>时总 nb</p>
<p></p>
        
      </div>
    </div>
      </div>
  </div>
  <!-- comment end -->
  
</div>
</main>